package com.dja.nzw.mq.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.common.collect.Lists;

import java.lang.reflect.Type;
import java.util.List;
import java.util.concurrent.Callable;

/**
 * Created by shuyun on 2017/7/15.
 */
public class FastJsonUtils {
    private static final SerializeConfig jsonConfig = new SerializeConfig();
    private static final ParserConfig parseConfig = ParserConfig.getGlobalInstance();
    private static SerializerFeature[] jsonFeatures;

    static {
        parseConfig.setAutoTypeSupport(true);
        List<SerializerFeature> serializerFeatureList = Lists.newArrayList();
        serializerFeatureList.add(SerializerFeature.WriteClassName);
        serializerFeatureList.add(SerializerFeature.SkipTransientField);
        serializerFeatureList.add(SerializerFeature.WriteDateUseDateFormat);

        jsonFeatures = serializerFeatureList.toArray(new SerializerFeature[serializerFeatureList.size()]);
    }

    static {
        jsonConfig.setAsmEnable(false);//由于当前版本的asm生成有一定问题,因此不再使用asm生成(在1.1.43以后的版本,asmFactory已被重构)
        parseConfig.setAsmEnable(false);//与上同理
    }

    /** 将对象输出为可反序列化的json字节数组 */
    public static <T> byte[] toJsonBytes(T t) {
        return JSON.toJSONBytes(t, jsonConfig, jsonFeatures);
    }

    /** 将对象输出为可反序列化的json字符串 */
    public static <T> String toJsonString(T t) {
        return JSON.toJSONString(t, jsonConfig, jsonFeatures);
    }

    private static <T> T _parse(Callable<T> call) {
        try{
            return call.call();
        } catch(Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    /**
     * 将json字节数组转换为指定的对象
     * 如果对象是按照指定的fastjson组织的，则转换为@type指定的对象，否则转换为JsonObject类型
     */
    @SuppressWarnings("unchecked")
    public static <T> T parse(byte[] bytes) {
        return _parse(() -> (T) JSON.parse(bytes));
    }

    /**
     * 将json字符串转换为指定的对象
     * 如果对象是按照指定的fastjson组织的，则转换为@type指定的对象，否则转换为JsonObject类型
     */
    @SuppressWarnings("unchecked")
    public static <T> T parse(String str) {
        return _parse(() -> (T) JSON.parse(str));
    }

    /** 将json字节数组转换为指定类型的对象 */
    @SuppressWarnings("unchecked")
    public static <T> T parse(byte[] bytes, Class<T> clazz) {
        return _parse(() -> (T) JSON.parseObject(bytes, clazz));
    }

    /** 将json字符串转换为指定类型的对象 */
    @SuppressWarnings("unchecked")
    public static <T> T parse(String str, Class<T> clazz) {
        return _parse(() -> JSON.parseObject(str, clazz));
    }

    /** 添加自定义序列化器 */
    public static void addSerializer(Type type, ObjectSerializer serializer) {
        jsonConfig.put(type, serializer);
    }

    /** 添加自定义反序列化器 */
    public static void addDerializer(Type type, ObjectDeserializer deserializer) {
        parseConfig.putDeserializer(type, deserializer);
    }
}
